package cn.qingfeng.a002_chat.server.handler;

import cn.qingfeng.a002_chat.server.groupsession.Group;
import cn.qingfeng.a002_chat.server.groupsession.GroupSession;
import cn.qingfeng.a002_chat.server.groupsession.GroupSessionFactory;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.internal.StringUtil;

import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@ChannelHandler.Sharable
public class GcreateHandler extends SimpleChannelInboundHandler<String> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        // "[fromUsername] gcreate [group name] [m1,m2,m3...]"
        final GroupSession groupSession = GroupSessionFactory.getSession();

        if (StringUtil.isNullOrEmpty(msg)) {
            return;
        }
        String[] msgArray = msg.split(" ");
        String instruction = msgArray[1];

        if ("gcreate".equals(instruction)) {
            String username = msgArray[0];
            String groupName = msgArray[2];
            String membersJsonStr = msgArray[3];
            Gson gson = new Gson();
            Type listType = new TypeToken<List<String>>() {
            }.getType();
            List<String> memberlist = gson.fromJson(membersJsonStr, listType);
            Set<String> memberSet = new HashSet<>(memberlist);
            Group group = groupSession.createGroup(groupName, memberSet);
            if (group == null) {
                ctx.writeAndFlush(groupName + " 创建成功！");
                List<Channel> membersChannel = groupSession.getMembersChannel(groupName);
                for (Channel channel : membersChannel) {
                    channel.writeAndFlush("您已被" + username + "拉入群：" + groupName);
                }
            } else {
                ctx.writeAndFlush("群已存在，请更改群名重试！");
            }
        } else {
            // 如果没有匹配上，就触发channelread事件，让消息继续向下一个handler传播。
            // > 因为这里所有的业务handler都是String类型的消息，通过if来区分，消息无法精确判断应该使用哪一个handler。
            // > 所以消息需要走遍所有的handler，一个一个试。
            // > 如果没有匹配上，就需要继续向下一个handler传递，继续匹配。
            // > 如果msg是特制的消息类就可以根据类型精确匹配到某个handler，就不需要fireChannelRead了。
            ctx.fireChannelRead(msg);
        }
    }
}